#region Namespace References

using System;
using DynConDevCorp.OpenArch.SmartData.Core.Metadata;
using DynConDevCorp.OpenArch.SmartData.Interfaces;
using DynConDevCorp.OpenArch.SmartData.Interfaces.MetaData;

#endregion

namespace DynConDevCorp.OpenArch.SmartData.Core
{
    public class SmartFactory : ISmartFactory
    {
        #region Constructors

        private SmartFactory()
        {
        }

        #endregion

        #region ISmartFactory Members

        public ISmartDisplayFormatter<TData> CreateDisplayFormatter<TData>(ParseHandler<TData> handler)
            where TData : IComparable<TData>
        {
            throw new NotImplementedException();
        }

        public ISmartEntity CreateEntityInstance()
        {
            throw new NotImplementedException();
        }

        public ISmartField<TData> CreateFieldInstance<TData>() where TData : IComparable<TData>
        {
            return new SmartField<TData>();
        }

        public ISmartField CreateInstance(Type fieldType)
        {
            return (ISmartField)Activator.CreateInstance(fieldType);
        }

        public ISmartField CreateFieldInstance(Type dataType)
        {
            Type rootType = typeof(SmartField<int>).GetGenericTypeDefinition();
            Type actualType = rootType.MakeGenericType(new[] { dataType });
            return (ISmartField)Activator.CreateInstance(actualType);
        }

        public ISmartEntityCollection CreateEntityCollection(Type entityType)
        {
            Type rootType = typeof(SmartEntityCollection<SmartDynamicEntity>).GetGenericTypeDefinition();
            Type actualType = rootType.MakeGenericType(new[] { entityType });
            return (ISmartEntityCollection) Activator.CreateInstance(actualType);
        }

        public ISmartInputParser<TData> CreateInputParser<TData>(ParseHandler<TData> handler)
        {
            throw new NotImplementedException();
        }

        public ISmartMetaEntity CreateMetaEntityInstance()
        {
            return new SmartMetaEntity(typeof(SmartDynamicEntity));
        }

        public ISmartEntity CreateEntityInstance(Type entityType)
        {
            return (ISmartEntity)Activator.CreateInstance(entityType);
        }

        public TTarget CreateEntityInstance<TTarget>(Guid EntityID)
          where TTarget : ISmartEntity
        {
            return (TTarget)Activator.CreateInstance(typeof(TTarget), new object[] { EntityID });
        }

        public TTarget CreateEntityInstance<TTarget>()
           where TTarget : ISmartEntity
        {
            return (TTarget)Activator.CreateInstance(typeof(TTarget));
        }

        #endregion

        #region Public Static Properties

        public static ISmartFactory GlobalInstance
        {
            get { return s_GlobalInstance; }
        }

        #endregion

        #region Fields and Constants

        private static readonly ISmartFactory s_GlobalInstance = new SmartFactory();

        #endregion
    }
}